import {reactive, UnwrapNestedRefs} from "vue";
import {CommonArea} from "@/Game/CommonArea";
import {PlayerArea} from "@/Game/PlayerArea";

export enum GameStage {
    None,
    Init,
    BeforePlayerOperation,
    PlayerPurchase,
    PlayerTrimDish,
    PlayerServe,
    End
}

export class Game {
    gameStage: GameStage;
    roundCount: number;
    activePlayerIndex: number;
    commonArea: UnwrapNestedRefs<CommonArea>;
    playerAreas: UnwrapNestedRefs<PlayerArea>[];

    showToast: boolean;
    toastText: string;
    toastDuration: number;

    showConfirmDialog: boolean;
    confirmDialogTitle: string;
    confirmDialogText: string;
    confirmDialogCallback: () => void;

    showNewGameDialog: boolean;
    lastWinnerIndex: number;
    checkWon: boolean;

    constructor() {
        this.gameStage = GameStage.None;
        this.commonArea = reactive(new CommonArea(this));
        this.playerAreas = [];
        this.lastWinnerIndex = -1;
        this.showNewGameDialog = true;
    }

    startNewGame(playerCount: number) {
        this.gameStage = GameStage.Init;
        this.roundCount = -1;
        this.activePlayerIndex = -1;
        this.showToast = false;
        this.showConfirmDialog = false;
        this.showNewGameDialog = false;
        this.checkWon = true;

        this.commonArea.startNewGame();
        this.playerAreas.length = 0;
        for (let i = 0; i < Math.min(playerCount, 4); i++) {
            this.playerAreas.push(reactive(new PlayerArea(this, i, i == 0)));
        }
        this.beforePlayerOperation();
    }

    beforePlayerOperation() {
        this.gameStage = GameStage.BeforePlayerOperation;
        this.activePlayerIndex = (++this.roundCount) % this.playerAreas.length;
        this.showToast = false;
        this.commonArea.beforePlayerOperation();
    }

    playerPurchase() {
        this.gameStage = GameStage.PlayerPurchase;
        this.commonArea.playerPurchase();
    }

    playerTrimDish() {
        this.gameStage = GameStage.PlayerTrimDish;
        this.playerAreas[this.activePlayerIndex].playerTrim();
    }

    playerServe() {
        this.gameStage = GameStage.PlayerServe;
        this.commonArea.playerServe();
    }

    end() {
        this.gameStage = GameStage.End;
        this.lastWinnerIndex = this.activePlayerIndex;
        this.showNewGameDialog = true;
    }

    continueAfterEnd() {
        this.checkWon = false;
        this.showNewGameDialog = false;
        this.beforePlayerOperation();
    }

    toast(text: string, duration: number = 4000) {
        this.toastText = text;
        this.toastDuration = duration;
        this.showToast = true;
    }

    confirm(title: string, text: string, callback: () => void) {
        this.confirmDialogTitle = title;
        this.confirmDialogText = text;
        this.confirmDialogCallback = callback;
        this.showConfirmDialog = true;
    }
}

export const game = reactive(new Game());